package com.distributed.lock.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @program: SpringBootDemos
 * @description: 单体应用下数据一致性问题
 * https://blog.csdn.net/zxd1435513775/article/details/122194202
 * @author: Kangsen
 * @create: 2022-07-12 15:51
 **/
@RestController
@Slf4j
public class SingleController {

    @Resource
    private RedisTemplate redisTemplate;

    //公平锁
    private ReentrantLock lock = new ReentrantLock(true);

    @GetMapping("/initStock")
    public String iniStock(){
        redisTemplate.opsForValue().set("goods:1",100);
        return "success";
    }

    /**
     * 用户购买某商品
     *
     * controller 是多例 这里就会存在并发线程安全问题
     *
     * @return
     */
    @GetMapping("/buy")
    public String buyGoods() {
        lock.lock();
        try{
            //查库存大于0时方可购买
            int stock = (int) redisTemplate.opsForValue().get("goods:1");
            if(stock > 0){
                //Long result = redisTemplate.opsForValue().decrement("goods:1");
                stock -= 1;
                log.info("库存:{}",stock);
                redisTemplate.opsForValue().set("goods:1",stock);
                return "购买商品成功，库存还剩"+stock+"件";
            }else{
                log.info("失败");
                return "购买失败，商品无库存";
            }
        }catch (Exception e){
            e.printStackTrace();
            return "异常"+e;
        }finally {
            lock.unlock();
        }
    }
}
